// Package api
// @Title api[简述该包的主要作用]
// @Description
// @Author  cnHuaShao
// @since v0.0.1
// @Version v1.0.0
// @Date 2024/4/21 22:37
// @Update 2024/4/21 22:37
package api

import (
	"FinancialManagement/src/base/baselog"
	"FinancialManagement/src/base/config"
	"FinancialManagement/src/base/mess"
	"FinancialManagement/src/business/application"
	"FinancialManagement/src/business/menu"
	"FinancialManagement/src/business/user"
	"FinancialManagement/src/business/util"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/go-session/session"
	"go.uber.org/zap"
)

const (
	CAPTCHA_KEY = "captchaKey"
	TOKEN_CODE  = "DATATOKEN" // 认证服务中jwt会话标记，用于存放在cookie中的标记
)

// GetMenuList
// @Description: 获取当前登录用户被授权的菜单列表
// @param c
func GetMenuList(c *gin.Context) {
	userId := c.GetString("LoginUserId")
	userInfo, err := user.ReadUserByID(userId)
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(500, err.Error()))
		return
	}
	menuList, err := menu.GetMenuInfoForRoleId(userInfo.RoleID)
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(500, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(menuList))
}

// GetUserInfo
// @Description: 获取用户信息
// @param c
func GetUserInfo(c *gin.Context) {
	userId := c.GetString("LoginUserId")
	userInfo, err := user.ReadUserByID(userId)
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(500, err.Error()))
		return
	}
	c.JSON(http.StatusOK, mess.ResMessOK(userInfo))
}

// AuthLogin
// @Description: 认证登录核心接口
// @param c
func AuthLogin(c *gin.Context) {
	baselog.Logger.Debug("接收到请求", zap.String("url", c.Request.URL.String()))
	// 1、打开session
	store, err := session.Start(c.Request.Context(), c.Writer, c.Request)
	if err != nil {
		http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
		return
	}
	// 2、验证验证码正确性是否有效
	// ck, t := store.Get(CAPTCHA_KEY)
	// if t {
	// s := time.Now().Second()
	// 判断验证码验证后的时间戳和当前时间戳差异化是否超过了60秒，如果超过则认定为已失效，未超过则通过。
	// if (s - ck.(int)) <= 60 {
	// 3、开始进行获取请求参数
	username := c.DefaultPostForm("account", "")
	password := c.DefaultPostForm("cipher", "")
	// 4、用户密码信息验证和其信息解析。
	userId, err := application.LoginUser(username, password)
	baselog.Logger.Debug("登录用户ID是：" + userId)
	if err != nil {
		c.JSON(http.StatusOK, mess.ResErrMess(90010050020, "账号密码错误"))
		return
	} else {
		// 5、用户登录成功，将该信息存放到session中，以便于后续如果再次认证时可以复用该用户信息
		store.Set("LoggedInUserID", userId)
		// 6、创建全局令牌，
		baselog.Logger.Info("登录成功")
		genToken, err := util.GenToken(userId)
		if err != nil {
			baselog.Logger.Error(err.Error())
			c.JSON(http.StatusOK, mess.ResErrMess(90010050021, "token生成错误"))
			return
		}
		// 7、存放到用户当前认证会话中，便于后续其他场景使用
		http.SetCookie(c.Writer, &http.Cookie{
			Name:  TOKEN_CODE,
			Value: genToken,
		})
		c.SetSameSite(http.SameSiteNoneMode)
		c.SetCookie(TOKEN_CODE, genToken, int(util.TokenExpireDuration.Seconds()), "/", config.Get().Base.Domain, false, false)
		baselog.Logger.Info("当前请求的SessionID是：" + store.SessionID())
		store.Save()
		c.Set(TOKEN_CODE, genToken)
		baselog.Logger.Debug("-----------------------------------------------")
		baselog.Logger.Debug("--------------------已完成登录-------------------")
		baselog.Logger.Debug("-----------------------------------------------")
		// 调用验证继承逻辑
		CallbackAuthentication(c)
	}
	/*}
	} else {
		// 验证码没有验证成功
		c.JSON(http.StatusOK, mess.ResErrMess("0x090010050018", "未进行验证码验证"))
		return
	}*/
}

// CallbackAuthentication
// @Description: 空白页面回调接口，页面登录成功回调接口
// @param c
func CallbackAuthentication(c *gin.Context) {
	baselog.Logger.Debug("进入验证回调逻辑，开始进行处理本次登录后的行为操作")
	uri := config.Get().Base.WebUrl + "login"
	dataToken := ""
	reqToken, ok := c.Get(TOKEN_CODE)
	if !ok {
		baselog.Logger.Debug("没有获取到内部传输的token，从会话中重新获取")
		// 获取JWT会话
		authHeader, err := c.Cookie(TOKEN_CODE)
		// 没有会话，开始进行跳转登录页面
		if err != nil || authHeader == "" {
			baselog.Logger.Debug("当前未登录，跳转到登录页面：" + err.Error())
			// 将相关参数传递到下一层，并跳转到登录页面
			// c.String(http.StatusFound, uri)
			c.JSON(http.StatusOK, mess.ResErrMess(1005001, uri))
			// c.Redirect(http.StatusFound, uri)
			return
		}
		dataToken = authHeader
	} else {
		baselog.Logger.Debug("已获取到会话JWT的TOKEN")
		dataToken = reqToken.(string)
	}
	baselog.Logger.Debug("token:" + dataToken)
	// 解析token包含的信息
	/*claims, err := util.ParseToken(dataToken)
	if err != nil {
		baselog.Logger.Debug("当前登录会话出现错误，跳转到登录页面重新登录", zap.String("uri", uri))
		baselog.Logger.Error(err.Error())
		c.String(http.StatusFound, uri)
		c.Abort()
		return
	}*/
	// c.Header("LoginUserId", claims.UserId)
	data := make(map[string]interface{})
	data["url"] = config.Get().Base.WebUrl + ""
	// data["url"] = ""
	data["dataToken"] = dataToken
	// 跳转到主页面即可，这里不写入用户编号是因为主页面有全局拦截器自动化注入用户编号
	c.JSON(http.StatusOK, mess.ResMessOK(data))
	c.Abort()
	return
}
